//////////////////////////////////////////////////////////////////////
//
// NO_IDVector.h header for the $1 class.
//
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
#ifndef NO_IDVector_H
#define NO_IDVector_H

//////////////////////////////////////////////////////////////////////////
#include "NO_Includes.h"

//////////////////////////////////////////////////////////////////////////
// class NO_IDVector definition
//////////////////////////////////////////////////////////////////////////
template<typename T>
class NO_IDVector  
{
public:
	//////////////////////////////////////////////////////////////////////
	typedef typename std::vector<T*>::iterator	iterator;
	typedef std::vector<T*>				Elements;
	typedef std::list<NO_UInt32 >		Free;

	//////////////////////////////////////////////////////////////////////
	// con/destruction
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////
	NO_IDVector(void){}
	~NO_IDVector(){}
	
	//////////////////////////////////////////////////////////////////////
	// operators
	//////////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////////////////////
	iterator begin	(void)			{return elements.begin();}
	iterator end	(void)			{return elements.end();}
	iterator find	(NO_UInt32 key)	{if(elements.size()<=key){throw NO_Error()<<"Out of Range";}return elements.begin()+key;}
	
	//////////////////////////////////////////////////////////////////////////
	NO_UInt32 erase(NO_UInt32 key)
	{
		if(elements.size()<=key){return 0;}
		
		Elements::iterator iter = elements.begin()+key;
		free.push_back(key);
		(*iter) = 0;
		
		return 1;
	}
	
	//////////////////////////////////////////////////////////////////////////
	NO_UInt32 insert(T& obj)
	{
		if(free.empty())
		{
			NO_UInt32 key = elements.size();
			elements.push_back(&obj);
			return key;
		}
		
		NO_UInt32 key = free.front();
		(*(elements.begin()+key)) = &obj;
		free.pop_front();
		
		return key;
	}
	
private:
	//////////////////////////////////////////////////////////////////////
	Elements elements;
	Free	 free;
};

#endif 